package com.vivo.ic.dm;

import android.net.Uri;

public final class Downloads {
    private Downloads() {
    }

    public static final class Column {
        // 数据id
        public static final String _ID = "_id";

        // 下载地址
        public static final String URI = "uri";

        // 想要DM使用的下载文件名
        public static final String FILE_NAME_HINT = "hint";

        // DM实际使用的下载文件名
        public static final String DATA = "_data";

        // 下载文件的类型（例如：mp3、apk之类）
        public static final String MIME_TYPE = "mimetype";

        // 控制DM下载过程中是否可见
        public static final String VISIBILITY = "visibility";

        // 下载是正在进行还是被暂停
        public static final String CONTROL = "control";

        // 下载的状态
        public static final String STATUS = "status";

        // 下载的最后修改时间
        public static final String LAST_MODIFICATION = "lastmod";

        // 通知发送时额外带的参数
        public static final String NOTIFICATION_EXTRAS = "notificationextras";

        // 下载时使用的userAgent
        public static final String USER_AGENT = "useragent";

        // 下载header中Cookie字段的值
        public static final String COOKIE_DATA = "cookiedata";

        // 下载header中Referer字段的值
        public static final String REFERER = "referer";

        // 服务器返回的etag字段，用于标记下载是否更改
        public static final String ETAG = "etag";

        // 下载文件的总大小
        public static final String TOTAL_BYTES = "total_bytes";

        // 现在已下载的文件大小
        public static final String CURRENT_BYTES = "current_bytes";

        // 当前下载速度
        public static final String CURRENT_SPEED = "current_speed";

        // 通知栏显示的title
        public static final String TITLE = "title";

        // 通知栏显示的content内容
        public static final String DESCRIPTION = "description";

        // 是否已被media扫描过
        public static final String MEDIA_SCANNED = "scanned";

        // 下载失败原因
        public static final String ERROR_MSG = "error_msg";

        // 已下载失败的次数
        public static final String FAILED_CONNECTIONS = "num_failed";

        // 重试下载的时间间隔（单位ms）
        public static final String RETRY_AFTER_X_REDIRECT_COUNT = "retry_x";

        // wifi切换到移动网络暂停下载时使用的标志位
        public static final String NETWORK_CHANGED = "network_changed";

        // 下载类型，单线程下载or多线程下载
        public static final String DOWNLOAD_TYPE = "download_type";

        /**
         * 设置已经下载完成的子线程数，解决问题：暂停下载时可能其中的1个子线程已经完成下，重启下载后即使所有子线程都下载完成，完成的子线程数还是小于mCountDownLatch.getCount()
         */
        public static final String COMPLETE_THREADS = "complete_threads";

        // 下载相关的包名信息
        public static final String PACKAGE_NAME = "package_name";

        // app自定义字段，预留5个
        public static final String APP_EXTRA_ONE = "extra_one";

        public static final String APP_EXTRA_TWO = "extra_two";

        public static final String APP_EXTRA_THREE = "extra_three";

        public static final String APP_EXTRA_FOUR = "extra_four";

        public static final String APP_EXTRA_FIVE = "extra_five";
    }

    public static final class Impl {
        public static String AUTHOR;

        public static Uri CONTENT_URI;

        public static final int CONTROL_RUN = 0;

        public static final int CONTROL_PAUSED = 1;

        /**
         * 下载过程中以及下载完成后，都会显示在通知栏
         */
        public static final int VISIBILITY_VISIBLE = 0;

        /**
         * 只有下载过程中才显示在通知栏
         */
        public static final int VISIBILITY_VISIBLE_PROGRESS = 1;

        /**
         * 只有下载完成后才显示在通知栏
         */
        public static final int VISIBILITY_VISIBLE_COMPLETED = 2;

        /**
         * 任何时候都不显示通知栏
         */
        public static final int VISIBILITY_HIDDEN = 3;


        /**
         * This download hasn't stated yet
         */
        public static final int STATUS_PENDING = 190;

        /**
         * This download has started
         */
        public static final int STATUS_RUNNING = 192;

        /**
         * This download has been paused by the owning app.
         */
        public static final int STATUS_PAUSED_BY_APP = 193;

        /**
         * This download encountered some network error and is waiting before retrying the request.
         */
        public static final int STATUS_WAITING_TO_RETRY = 194;

        /**
         * This download is waiting for network connectivity to proceed.
         */
        public static final int STATUS_WAITING_FOR_NETWORK = 195;

        /**
         * This download exceeded a size limit for mobile networks and is waiting for a Wi-Fi
         * connection to proceed.
         */
        public static final int STATUS_QUEUED_FOR_WIFI = 196;

        /**
         * This download couldn't be completed due to insufficient storage
         * space.  Typically, this is because the SD card is full.
         */
        public static final int STATUS_INSUFFICIENT_SPACE_ERROR = 198;

        /**
         * This download couldn't be completed because no external storage
         * device was found.  Typically, this is because the SD card is not
         * mounted.
         */
        public static final int STATUS_DEVICE_NOT_FOUND_ERROR = 199;

        /**
         * This download has successfully completed.
         * Warning: there might be other status values that indicate success
         * in the future.
         * Use isSucccess() to capture the entire category.
         */
        public static final int STATUS_SUCCESS = 200;

        /**
         * This request couldn't be parsed. This is also used when processing
         * requests with unknown/unsupported URI schemes.
         */
        public static final int STATUS_BAD_REQUEST = 400;

        /**
         * This download can't be performed because the content type cannot be
         * handled.
         */
        public static final int STATUS_NOT_ACCEPTABLE = 406;

        /**
         * This download cannot be performed because the length cannot be
         * determined accurately. This is the code for the HTTP error "Length
         * Required", which is typically used when making requests that require
         * a content length but don't have one, and it is also used in the
         * client when a response is received whose length cannot be determined
         * accurately (therefore making it impossible to know when a download
         * completes).
         */
        public static final int STATUS_LENGTH_REQUIRED = 411;

        /**
         * This download was interrupted and cannot be resumed.
         * This is the code for the HTTP error "Precondition Failed", and it is
         * also used in situations where the client doesn't have an ETag at all.
         */
        public static final int STATUS_PRECONDITION_FAILED = 412;

        /**
         * The lowest-valued error status that is not an actual HTTP status code.
         */
        public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;

        /**
         * The requested destination file already exists.
         */
        public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;

        /**
         * Some possibly transient error occurred, but we can't resume the download.
         */
        public static final int STATUS_CANNOT_RESUME = 489;

        /**
         * This download was canceled
         */
        public static final int STATUS_CANCELED = 490;

        /**
         * This download has completed with an error.
         * Warning: there will be other status values that indicate errors in
         * the future. Use isStatusError() to capture the entire category.
         */
        public static final int STATUS_UNKNOWN_ERROR = 491;

        /**
         * This download couldn't be completed because of a storage issue.
         * Typically, that's because the filesystem is missing or full.
         * Use the more specific {@link #STATUS_INSUFFICIENT_SPACE_ERROR}
         * and {@link #STATUS_DEVICE_NOT_FOUND_ERROR} when appropriate.
         */
        public static final int STATUS_FILE_ERROR = 492;

        /**
         * This download couldn't be completed because of an HTTP
         * redirect response that the download manager couldn't
         * handle.
         */
        public static final int STATUS_UNHANDLED_REDIRECT = 493;

        /**
         * This download couldn't be completed because of an
         * unspecified unhandled HTTP code.
         */
        public static final int STATUS_UNHANDLED_HTTP_CODE = 494;

        /**
         * This download couldn't be completed because of an
         * error receiving or processing data at the HTTP level.
         */
        public static final int STATUS_HTTP_DATA_ERROR = 495;

        /**
         * This download couldn't be completed because of an
         * HttpException while setting up the request.
         */
        public static final int STATUS_HTTP_EXCEPTION = 496;

        /**
         * This download couldn't be completed because there were
         * too many redirects.
         */
        public static final int STATUS_TOO_MANY_REDIRECTS = 497;

        private Impl() {
        }

        protected static void setAuthor(String author) {
            AUTHOR = author;
            CONTENT_URI = Uri.parse("content://" + AUTHOR + "/all_downloads");
        }


        /*
         * Lists the states that the download manager can set on a download
         * to notify applications of the download progress.
         * The codes follow the HTTP families:<br>
         * 1xx: informational<br>
         * 2xx: success<br>
         * 3xx: redirects (not used by the download manager)<br>
         * 4xx: client errors<br>
         * 5xx: server errors
         */

        /**
         * Returns whether the status is informational (i.e. 1xx).
         */
        public static boolean isStatusInformational(int status) {
            return (status >= 100 && status < 200);
        }

        /**
         * Returns whether the status is a success (i.e. 2xx).
         */
        public static boolean isStatusSuccess(int status) {
            return (status >= 200 && status < 300);
        }

        /**
         * Returns whether the status is an error (i.e. 4xx or 5xx).
         */
        public static boolean isStatusError(int status) {
            return (status >= 400 && status < 600)
                    || (status == Impl.STATUS_INSUFFICIENT_SPACE_ERROR);
        }

        /**
         * Returns whether the status is a client error (i.e. 4xx).
         */
        public static boolean isStatusClientError(int status) {
            return (status >= 400 && status < 500);
        }

        /**
         * Returns whether the status is a server error (i.e. 5xx).
         */
        public static boolean isStatusServerError(int status) {
            return (status >= 500 && status < 600);
        }

        /**
         * Returns whether the download has completed (either with success or
         * error).
         */
        public static boolean isStatusCompleted(int status) {
            return (status >= 200 && status < 300) || (status >= 400 && status < 600)
                    || (status == Impl.STATUS_INSUFFICIENT_SPACE_ERROR);
        }

        /**
         * 是否是手动暂停下载（如浏览器下载管理页面点暂停）
         *
         * @param status
         * @param control
         * @return
         */
        public static boolean isPausedManually(int status, int control) {
            return (status == Downloads.Impl.STATUS_PAUSED_BY_APP || status == Downloads.Impl.STATUS_WAITING_TO_RETRY)
                    && control == Downloads.Impl.CONTROL_PAUSED;
        }

        public static String statusToString(int status) {
            switch (status) {
            case STATUS_PENDING:
                return "PENDING";
            case STATUS_RUNNING:
                return "RUNNING";
            case STATUS_PAUSED_BY_APP:
                return "PAUSED_BY_APP";
            case STATUS_WAITING_TO_RETRY:
                return "WAITING_TO_RETRY";
            case STATUS_WAITING_FOR_NETWORK:
                return "WAITING_FOR_NETWORK";
            case STATUS_QUEUED_FOR_WIFI:
                return "QUEUED_FOR_WIFI";
            case STATUS_INSUFFICIENT_SPACE_ERROR:
                return "INSUFFICIENT_SPACE_ERROR";
            case STATUS_DEVICE_NOT_FOUND_ERROR:
                return "DEVICE_NOT_FOUND_ERROR";
            case STATUS_SUCCESS:
                return "SUCCESS";
            case STATUS_BAD_REQUEST:
                return "BAD_REQUEST";
            case STATUS_NOT_ACCEPTABLE:
                return "NOT_ACCEPTABLE";
            case STATUS_LENGTH_REQUIRED:
                return "LENGTH_REQUIRED";
            case STATUS_PRECONDITION_FAILED:
                return "PRECONDITION_FAILED";
            case STATUS_FILE_ALREADY_EXISTS_ERROR:
                return "FILE_ALREADY_EXISTS_ERROR";
            case STATUS_CANNOT_RESUME:
                return "CANNOT_RESUME";
            case STATUS_CANCELED:
                return "CANCELED";
            case STATUS_UNKNOWN_ERROR:
                return "UNKNOWN_ERROR";
            case STATUS_FILE_ERROR:
                return "FILE_ERROR";
            case STATUS_UNHANDLED_REDIRECT:
                return "UNHANDLED_REDIRECT";
            case STATUS_UNHANDLED_HTTP_CODE:
                return "UNHANDLED_HTTP_CODE";
            case STATUS_HTTP_DATA_ERROR:
                return "HTTP_DATA_ERROR";
            case STATUS_HTTP_EXCEPTION:
                return "HTTP_EXCEPTION";
            case STATUS_TOO_MANY_REDIRECTS:
                return "TOO_MANY_REDIRECTS";
            default:
                return Integer.toString(status);
            }
        }
    }

    /**
     * Constants related to HTTP request headers associated with each download.
     */
    public static class RequestHeaders {
        public static final String HEADERS_DB_TABLE = "request_headers";
        public static final String COLUMN_DOWNLOAD_ID = "download_id";
        public static final String COLUMN_HEADER = "header";
        public static final String COLUMN_VALUE = "value";

        /**
         * Path segment to add to a download URI to retrieve request headers
         */
        public static final String URI_SEGMENT = "headers";

        /**
         * Prefix for ContentValues keys that contain HTTP header lines, to be passed to
         * DownloadProvider.insert().
         */
        public static final String INSERT_KEY_PREFIX = "http_header_";
    }

    public class Action {

        private static final String ACTION_PRE = "DM_ACTION_";

        public static final String DOWNLOAD_RETRY = ACTION_PRE + "DOWNLOAD_RETRY";

        public static final String NOTI_DOWNLOAD_CLICKED = ACTION_PRE + "NOTI_DOWNLOAD_CLICKED";

        public static final String NOTI_COMPLETE_CLICKED = ACTION_PRE + "NOTI_COMPLETE_CLICKED";

        public static final String NOTI_HIDE = ACTION_PRE + "NOTI_HIDE";

        /**
         * 下载任务暂停通知栏
         */
        public static final String NOTI_CONFIRM = ACTION_PRE + "NOTI_CONFIRM";
    }
}
